#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDebug>
#include <QDateTime>

#define MY_VID 0x1fc9
#define MY_PID 0x00a2

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    usb_init(); /* initialize the library */
    usb_find_busses(); /* find all busses */
    usb_find_devices(); /* find all connected devices */

    my_usb_get_device_list();
    if (!(udev = open_dev())) {
        qDebug("error opening device: %s", usb_strerror());
        exit(1);
    } else
        qDebug("open success: device %04X:%04X opened", MY_VID, MY_PID);
    printf_device_descriptor(&dev->descriptor);
    timer = new QTimer(this);
    connect(timer,SIGNAL(timeout()),this,SLOT(usbReadTimeout()));
    timer->start(100);
    //usb_close(udev);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::my_usb_get_device_list()
{
   struct usb_bus *bus;
   struct usb_device *dev;

   for (bus = usb_get_busses(); bus; bus = bus->next) {
       for (dev = bus->devices; dev; dev = dev->next) {
           qDebug("VID:VID = %x:%x\n", dev->descriptor.idVendor, dev->descriptor.idProduct);
       }
   }
}

usb_dev_handle *MainWindow::open_dev()
{
    struct usb_bus *bus;
    //struct usb_device *dev;
    for(bus = usb_get_busses(); bus; bus = bus->next) {
        for(dev = bus->devices; dev; dev = dev->next) {
            if((dev->descriptor.idVendor == MY_VID) && (dev->descriptor.idProduct == MY_PID)) {
                qDebug("open dev...\n");
                    return usb_open(dev);
            }
        }
    }
    return NULL;
}

void MainWindow::printf_device_descriptor(usb_device_descriptor *desc)
{
    qDebug("bLength:             %u",     desc->bLength);
    qDebug("bDescriptorType:     %02Xh",  desc->bDescriptorType);
    qDebug("bcdUSB:              %04Xh",  desc->bcdUSB);
    qDebug("bDeviceClass:        %02Xh",  desc->bDeviceClass);
    qDebug("bDeviceSubClass:     %02Xh",  desc->bDeviceSubClass);
    qDebug("bDeviceProtocol:     %02Xh",  desc->bDeviceProtocol);
    qDebug("bMaxPacketSize0:     %02Xh",  desc->bMaxPacketSize0);
    qDebug("idVendor:            %04Xh",  desc->idVendor);
    qDebug("idProduct:           %04Xh",  desc->idProduct);
    qDebug("bcdDevice:           %04Xh",  desc->bcdDevice);
    qDebug("iManufacturer:       %u",     desc->iManufacturer);
    qDebug("iProduct:            %u",     desc->iProduct);
    qDebug("iSerialNumber:       %u",     desc->iSerialNumber);
    qDebug("bNumConfigurations:  %u",     desc->bNumConfigurations);
}


//Report Type
#define REPORT_INPUT 0x01
#define REPORT_OUTPUT 0x02
#define REPORT_FEATURE 0x03
//request
#define GET_REPORT 0x01
#define GET_IDLE 0x02
#define GET_PROTOCOL 0x03
#define SET_REPORT 0x09
#define SET_IDLE 0x0A
#define SET_PROTOCOL 0x0B
//Request Type
#define GET_REPORT_REQUESTTYPE 0xA1
#define GET_IDLE_REQUESTTYPE 0xA1
#define GET_PROTOCOL_REQUESTTYPE 0xA1
#define SET_REPORT_REQUESTTYPE 0x21
#define SET_IDLE_REQUESTTYPE 0x21
#define SET_PROTOCOL_REQUESTTYPE 0x21
int MainWindow::SetOutputReport(usb_dev_handle *handle, unsigned char id, char *data, unsigned char size)
{
    int value = (REPORT_OUTPUT<<8) | id ;
    int bIndex = 0x0000; //end point 0
    int ret;
    ret = usb_control_msg(handle, SET_REPORT_REQUESTTYPE, SET_REPORT, value, bIndex, data, size, 1000);
    if(ret <0)
    {
    //error
    }
    qDebug("SetOutputReport ret: %d\r\n", ret);
    return ret;
}

int MainWindow::hid_write(usb_dev_handle *handle, char *data, size_t length)
{
    int ret;
    ret=usb_interrupt_write(handle, 2,data, length,1000);
    qDebug("SetOutputReport ret: %d\r\n", ret);
}

#define MY_INTERFACE_0 0
void MainWindow::on_pushButton_clicked()
{
    int ret;
    static char data[8] = {0x01,0x02,0x03,0x04,0x05,0x06,0x07,0x08};
    if(udev)
    {
        if(usb_claim_interface(udev, MY_INTERFACE_0) < 0)
        {
        qDebug("Fail to set claim interface 0: %s", usb_strerror());
        return;
        }
        data[0]++;
        //ret = SetOutputReport(udev, 4,&data ,1); //发送数据到设备
         ret = hid_write(udev,data ,8); //发送数据到设备
        usb_release_interface(udev, MY_INTERFACE_0);
        if(ret <0)
        {
            qDebug("error: %d\r\n", ret);
        }
    }
}

void MainWindow::usbReadTimeout()
{
    int ret;
    char dataRaw[8];
    if(udev)
    {
        if(usb_claim_interface(udev, MY_INTERFACE_0) < 0)
        {
        qDebug("Fail to set claim interface0, Please check USB connect\r\n", ret);
        return;
        }
        usb_clear_halt(udev, MY_INTERFACE_0);
        ret = usb_interrupt_read(udev, EP_IN, dataRaw, 8, 100);
        if(-116 == ret)
        {
            //qDebug("time out because no data can be read\n");
        }
        else if(-5 == ret)
        {
            qDebug("Error: USB unconnected\n");
        }
        else if(ret < 0)
        {
            qDebug()<< usb_strerror();
            qDebug()<<("usb_interrupt_read error\n"+QString("Ret%1\n").arg(ret));
        } else
        {
            QString str("R: ");
            int i=0;
            while(i < ret)
            {
                str += QString().number(dataRaw[i],10) + " ";
                i++;
            }
            qDebug()<< QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss")<<"  "<<str+"\n";
        }
        usb_release_interface(udev, MY_INTERFACE_0);
    }
}
